package zd.vrp.operator;

import java.util.List;

import zd.vrp.global.City;
import zd.vrp.global.Route;
import zd.vrp.initsolution.InsertionObject;
import zd.vrp.initsolution.SolomonParameter;

public class Repair {
	public List<Route> repairInsertion(City city, List<Route> childRouteList) {
		InsertionObject io = new InsertionObject();
		io.currentBestCity = city;
		int routeNum = 0;
		int cityPosition = 0;
		
		//1. iterate each route
		for(int i=0;i<childRouteList.size();i++){
			
			Route currentRoute = childRouteList.get(i);
			
			//1.1 first check whether this new inserted city satisfies capacity requirement
			if(currentRoute.checkDemandFeasibility(city)==false){
				continue;
			}
			//2. for each possible insertion position
			for(int j=1;j<currentRoute.getCityList().size();j++){
				//2.1 check whether insertion to this position violate time window
				if(currentRoute.checkTimeFeasibility(city, j)==false){
					continue;
				}
				//2.2 calculate c11 and c12
				City followingCity = currentRoute.getCityList().get(j);
				double c11 = currentRoute.getInsertionDistanceCostSolomonI(city, j);
				double c12 = currentRoute.getStartTimeOfFollowingCityAfterInsertion(city, j)-followingCity.getEtime();
				
				double c1 = SolomonParameter.alpha1*c11+SolomonParameter.alpha2*c12;
				
				//2.3 compare c1 with current best value
				if(c1<io.currentBestInsertionValue){
					io.currentBestInsertionValue = c1;
					io.currentBestRoute = currentRoute;
					io.currentBestPosition = j;			
					routeNum = i;
					cityPosition = j;
				}
			}
		}
		if(io.currentBestRoute == null){
			return null;		
		}
		else {
			childRouteList.get(routeNum).insertCityIntoRoute(city,cityPosition);
			return childRouteList;
		}
	}

}
